#include "list.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

node_t *list_create(void)
{
    node_t *head = NULL;

    // 创建头结点空间
    head = malloc(sizeof(node_t));
    if (head == NULL)
    {
        perror("malloc failed...");
        goto err0;
    }
    memset(head, 0, sizeof(node_t));

    head->next = NULL;

    return head;

err0:
    return NULL;
}

int list_append(node_t *head, int num)
{
    node_t *new_node = NULL;
    node_t *tmp = NULL;

    // 参数检查
    if (NULL == head)
    {   
        perror("argument lawless...");
        goto err0;
    }

    // 创建节点
    new_node = malloc(sizeof(node_t));
    if (NULL == new_node)
    {
        perror("new_node malloc failed...");
        goto err0;
    }
    memset(new_node, 0, sizeof(node_t));

    // 写入数据
    new_node->num = num;
    new_node->next = NULL;

    // 尾部插入链表
    tmp = head;
    while (NULL != tmp->next)
    {
        tmp = tmp->next;
    }
    tmp->next = new_node;

    return 0;

err0:
    return -1;
}

int list_traverse(node_t *head)
{
    node_t *tmp = NULL;

    // 参数检查
    if (NULL == head)
    {
        perror("head null...");
        goto err0;
    }

    tmp = head->next;

    // 遍历
    while (NULL != tmp)
    {
        printf("%d ", tmp->num);
        tmp = tmp->next;
    }
    printf("\n");



    return 0;   

err0:
    return -1;
}

int list_destroy(node_t *head)
{
    node_t *tmp = NULL;
    node_t *save = NULL;

    // 参数检查
    if (NULL == head)
    {
        perror("head null...");
        goto err0;
    }

    tmp = head;
    // 释放空间
    while (NULL != tmp)
    {
        // 保存下一个节点
        save = tmp->next;

        // 销毁
        free(tmp);
        tmp = NULL;

        // 指向下一个节点
        tmp = save;
    }


    return 0;


err0:
    return -1;
}

int list_prepend(node_t *head, int num)
{
    node_t *tmp = NULL;
    node_t *new_node = NULL;

    // 参数检查
    if (NULL == head)
    {
        perror("head is null...");
        goto err0;
    }

    // 创建节点
    new_node = malloc(sizeof(node_t));
    if (NULL == new_node)
    {
        perror("malloc failed...");
        goto err0;
    }
    memset(new_node, 0, sizeof(node_t));

    // 写入数据
    new_node->next = NULL;
    new_node->num = num;

    // 头部插入链表
    tmp = head->next;
    new_node->next = tmp;
    head->next = new_node;


    return 0;

err0:
    return -1;
}

// index 从1开始
int list_insert_by_index(node_t *head, int num, int index)
{
    int list_len = 0;
    node_t *tmp = NULL;
    int idx = index - 1;
    node_t *new_node = NULL;
    int i = 0;

    // 参数检查
    if (NULL == head)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 指向检查
    if (idx < 0)
    {
        perror("index lawless...");
        goto err0;
    }

    // 获取链表的长度
    tmp = head->next;       // 通用

    while (NULL != tmp)
    {
        list_len++;
        tmp = tmp->next;
    }
    tmp = head->next;

    // 判断指向极端
    if (idx == 0)
    {
        // 指向0 头插
        list_prepend(head, num);
    }
    else if (idx >= list_len)
    {
        // 指向结束后 尾插
        list_append(head, num);
    }
    else 
    {
        // 创建节点
        new_node = malloc(sizeof(node_t));
        if (NULL == new_node)
        {
            perror("malloc failed...");
            goto err0;
        }   
        memset(new_node, 0, sizeof(node_t));

        // 写入数据
        new_node->num = num;

        // 插入节点
        for (i = 0; i < idx - 1; i++)
        {
            tmp = tmp->next;
        }
        new_node->next = tmp->next;
        tmp->next = new_node;
    }



    return 0;

err0:
    return -1;
}



int list_reverse(node_t *head)
{
    node_t *tmp = NULL;
    node_t *save = NULL;

    // 参数检查
    if (NULL == head)
    {
        perror("head not exit...");
        goto err0;
    }

    // 断开链表
    tmp = head->next;
    head->next = NULL;

    // 反转
    while (tmp != NULL)
    {
        // 保存后节点
        save = tmp->next;

        // 链表头插
        tmp->next = head->next;
        head->next = tmp;

        // 指向下一个节点
        tmp = save;
    }
    
    return 0;

err0:
    return -1;
}
